/*
 *  ObjectPoolAllocator.h
 *  MusicAnalyzer
 *
 *  Created by jiro on 12/03/30.
 *  Copyright 2012 jiro music. All rights reserved.
 *
 */

#pragma once

#include <vector>
#include <stack>
#include <queue>

namespace sc
{
	/*	@remark simple pool allocator.
			static class, thread un safe.
	*/
	template< class Type, int identifier = 0 >
	class PoolAllocator
	{
	public:

		static void Allocate( int instanceCount )
		{
			if ( instanceCount <= 0 )
			{
				instanceCount = 1;
			}
			Type* ptr = new Type[ instanceCount ];
			for ( int i = 0; i < instanceCount; i++ )
			{
				instances.push_back( & ptr[ i ] );
				cleanStack.push( & ptr[ i ] );
			}
			ptrs.push_back( ptr );
		}

		static void DeallocateAll()
		{
			for ( int i = 0, count = ptrs.size(); i < count; i++ )
			{
				delete [] ptrs[ i ];
			}
			instances.clear();
			instances.resize( 0 );
			ptrs.clear();
			ptrs.resize( 0 );
			while ( not cleanStack.empty() )
			{
				cleanStack.pop();
			}
		}

		static Type* GetInstance()
		{
			if ( cleanStack.empty() )
			{
				Allocate( instances.size() );
			}
			Type* instance = cleanStack.top();
			cleanStack.pop();
			return instance;
		}
		
		static void ReturnInstance( Type* type )
		{
			cleanStack.push( type );
		}

		static int GetInstanceCount()
		{
			return instances.size();
		}

	private:

		static std::vector< Type* > instances;

		static std::stack< Type* > cleanStack;

		static std::vector< Type* > ptrs;			//	ptrs to safe dealloc
	};

	template< class Type, int identifier >
	std::vector< Type* > PoolAllocator< Type, identifier >::instances;

	template< class Type, int identifier >
	std::stack< Type* > PoolAllocator< Type, identifier >::cleanStack;

	template< class Type, int identifier >
	std::vector< Type* > PoolAllocator< Type, identifier >::ptrs;

}